package com.cn.fangshuo.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cn.fangshuo.entity.CarWash;
import com.cn.fangshuo.entity.CarWashPushLog;
import com.cn.fangshuo.entity.CarWashShandongAddInfo;
import com.cn.fangshuo.enums.LicensePlateColorEnum;
import com.cn.fangshuo.service.ICarWashPushLogService;
import com.cn.fangshuo.service.ICarWashService;
import com.cn.fangshuo.service.ICarWashShandongAddInfoService;
import com.cn.fangshuo.util.HmacSha256Util;
import com.cn.fangshuo.util.StrUtil;
import com.cn.fangshuo.util.TimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.StringJoiner;


@Component
public class PushShanDongCarWashTask {

    private static final Logger logger = LoggerFactory.getLogger(PushShanDongCarWashTask.class);

    @Autowired
    private ICarWashService carWashService;

    @Autowired
    private ICarWashShandongAddInfoService carWashShandongAddInfoService;

    @Autowired
    private ICarWashPushLogService carWashPushLogService;

    private final String baseURL = "http://iot-iot.deepthen.com";

    private final String authId = "qxsptgnq54n";

    private final String authSecret = "m9j2xv1lj140fc7r";

    private final String productId = "5zg41368nvo";

    private final String productSecret = "f53c1r17xehjtbnv";

    @Scheduled(fixedRate = 5 * 60 * 1000)
    public void push() {

        carWashShandongAddInfoService.list(new LambdaQueryWrapper<>()).parallelStream().forEach(carWashShandongAddInfo -> {
            LocalDateTime endTime = LocalDateTime.now();
            LocalDateTime startTime;

            String deviceId = carWashShandongAddInfo.getDeviceUuid();
            String lastCarWashPushTime = TimeUtil.format(carWashShandongAddInfo.getLastPushTime());
            if (StrUtil.isBlank(lastCarWashPushTime)){
                startTime = LocalDateTime.now().minusMinutes(5);
            } else {
                startTime = TimeUtil.parseLocalDateTime(lastCarWashPushTime);
            }

            List<CarWash> list = carWashService.list(new LambdaQueryWrapper<CarWash>().ge(CarWash::getCreateTime, startTime).lt(CarWash::getCreateTime, endTime).eq(CarWash::getDeviceUuid, deviceId));
            Long pushId = carWashShandongAddInfo.getPushId();
            if (CollUtil.isNotEmpty(list)){
                logger.info("==========推送山东车冲信息开始：{}====================", TimeUtil.format(endTime));
                for (CarWash carWash : list){
                    pushId++;
                    Long timestamp = System.currentTimeMillis();
                    String timestampStr = String.valueOf(timestamp);

                    JSONObject params = new JSONObject();
                    params.put("vehicleNo", carWash.getLicensePlateNum());
                    params.put("plateType", LicensePlateColorEnum.getByLicensePlateColor(carWash.getLicensePlateColor()).getShandongCode());
                    params.put("plateColor", LicensePlateColorEnum.getByLicensePlateColor(carWash.getLicensePlateColor()).getDesc());
                    params.put("washStatus", carWash.getEvent() > 2 ? 4 : 2);
                    params.put("washDuration", carWash.getWashTotalDuration());
                    params.put("image", carWash.getImages().split(",")[0]);
                    params.put("video", carWash.getVideoUrl());
                    params.put("datetime", TimeUtil.format(carWash.getCreateTime()));

                    JSONObject args = new JSONObject();
                    args.put("id", pushId.toString());
                    args.put("version", "1.0");
                    args.put("params", params);
                    args.put("time", timestamp);
                    args.put("method", "thing.event.record.post");

                    CarWashPushLog log = new CarWashPushLog();
                    log.setDeviceUuid(deviceId);
                    log.setCarWashTime(TimeUtil.parseLocalDateTime(carWash.getWashTime()));
                    log.setParams(args.toJSONString());
                    log.setCreateTime(LocalDateTime.now());

                    logger.info("==========request信息：{}====================", args.toJSONString());
                    try (HttpResponse response = HttpRequest.post(baseURL + "/iot/thing/event/post")
                            .header("Content-Type", "multipart/form-data")
                            .header("sign", HmacSha256Util.hmacSha256Hex(getSign(deviceId, timestampStr), authSecret + getDeviceSecret(carWashShandongAddInfo) + productSecret))
                            .form("authId", authId)
                            .form("productId", productId)
                            .form("deviceId", deviceId)
                            .form("event", "record")
                            .form("args", args.toJSONString())
                            .form("timestamp", timestamp)
                            .execute()) {
                        log.setSuccess(response.isOk());
                        log.setReponse(response.body());
                        logger.info("==========response信息：{}====================", response.body());
                    } catch (Exception e) {
                        logger.error("推送山东车冲信息失败：{}", e.getMessage(), e);
                        log.setSuccess(false);
                        log.setReponse(e.getMessage());
                    }

                    carWashPushLogService.save(log);
                }
                logger.info("==========推送山东车冲信息结束：{}====================", TimeUtil.format(endTime));
            }

            carWashShandongAddInfo.setPushId(pushId);
            carWashShandongAddInfo.setLastPushTime(endTime);
            carWashShandongAddInfo.setUpdateTime(LocalDateTime.now());
            carWashShandongAddInfoService.updateById(carWashShandongAddInfo);
        });
    }

    private String getDeviceSecret(CarWashShandongAddInfo carWashShandongAddInfo){
        if (StrUtil.isNotEmpty(carWashShandongAddInfo.getDeviceSecret())){
            return carWashShandongAddInfo.getDeviceSecret();
        }

        String timestamp = String.valueOf(System.currentTimeMillis());
        try (HttpResponse response = HttpRequest.post(baseURL + "/device/open/register")
                .header("Content-Type", "multipart/form-data")
                .header("sign", HmacSha256Util.hmacSha256Hex(getSign(carWashShandongAddInfo.getDeviceUuid(), timestamp), authSecret + productSecret))
                .form("authId", authId)
                .form("productId", productId)
                .form("deviceId", carWashShandongAddInfo.getDeviceUuid())
                .form("timestamp", timestamp)
                .execute()) {
            if (response.isOk()) {
                String deviceSecret = JSONObject.parseObject(response.body()).getJSONObject("data").getString("secret");
                carWashShandongAddInfo.setDeviceSecret(deviceSecret);
                return deviceSecret;
            }
        } catch (Exception e) {
            logger.error("获取设备密钥失败：{}", e.getMessage(), e);
        }
        return null;
    }

    private String getSign(String deviceId, String timestamp){
        StringJoiner sign = new StringJoiner("_");
        sign.add("authId");
        sign.add(authId);
        sign.add("deviceId");
        sign.add(deviceId);
        sign.add("productId");
        sign.add(productId);
        sign.add("timestamp");
        sign.add(timestamp);
        return sign.toString();
    }
}
